﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;

namespace Derbster.Domain
{
    public enum BoxEventType
    {
        Seated,
        Released
    }
    public class BoxEvent : IEquatable<BoxEvent>
    {
        [ContractVerification(false)]
        internal BoxEvent()
        {

        }

        public BoxEvent(Match match, Player player, int period, int jamNumber, BoxEventType boxEventType, int rank)
        {
            Contract.Requires(player != null);
            Contract.Requires(period == 1 || period == 2);
            Contract.Requires(jamNumber > 0);

            BoxEventType = boxEventType;
            Match = match;
            Player = player;
            Period = period;
            JamNumber = jamNumber;
            Rank = rank;
        }

        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int BoxEventId { get; internal set; }
        public Match Match { get; internal set; }
        public Player Player { get; internal set; }
        public int Period { get; internal set; }
        public int JamNumber { get; internal set; }
        public BoxEventType BoxEventType { get; internal set; }
        public int Rank { get; internal set; }

        public bool Equals(BoxEvent other)
        {
            if (ReferenceEquals(null, other))
            {
                return false;
            }
            if (ReferenceEquals(this, other))
            {
                return true;
            }
            return Equals(Player, other.Player) 
                && Equals(Match, other.Match)
                && Period == other.Period 
                && JamNumber == other.JamNumber 
                && BoxEventType == other.BoxEventType;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj))
            {
                return false;
            }
            if (ReferenceEquals(this, obj))
            {
                return true;
            }
            if (obj.GetType() != this.GetType())
            {
                return false;
            }
            return Equals((BoxEvent)obj);
        }

        public override int GetHashCode()
        {
            Contract.Assume(this.Match != null);
            unchecked
            {
                int hashCode = (Player != null ? Player.GetHashCode() : 0);
                hashCode = (hashCode * 397) ^ Match.GetHashCode();
                hashCode = (hashCode * 397) ^ Period;
                hashCode = (hashCode * 397) ^ JamNumber;
                hashCode = (hashCode * 397) ^ (int)BoxEventType;
                return hashCode;
            }
        }
    }
}
